<?php
/**
 * Created by PhpStorm.
 * User: guokunsheng
 * Date: 2018/6/6
 * Time: 17:38
 */

namespace app\common\model;

use app\common\lib\exception\ApiException;
use think\Cache;
use think\Db;
use think\Log;
use traits\model\SoftDelete;

class LuckyPlanet extends Base
{
    /**
     * 用户所有获取的幸运星的id（+uid）
     */
    const REDIS_KEY_IDS = 'lucky_planet_ids_';
    /**
     * 幸运星详情（+id）
     */
    const REDIS_KEY_DETAIL = 'lucky_planet_detail_';
    /**
     * 今日中奖详情（+日期Ymd）
     */
    const WIN_TODAY = 'winner_today';
    /**
     * 用户今日抽奖情况（+ $uid_日期YMD ）
     */
    const LUCKY_PLANET_USER_DATE = 'lucky_planet_user_';
    /**
     * 所有幸运星奖项
     */
    const LUCKY_PLANET_PRIZE = 'lucky_planet_prize';
    /**
     * 所有奖项提示语
     */
    const LUCKY_PLANET_PRIZE_TIPS = 'lucky_planet_prize_tips';

    protected $table = 'wechat_backup_07_18_14_43_00.app_user_lucky_num';
    use SoftDelete;

    protected $deleteTime = 'delete_time';

    /**
     * 获取今日抽奖总次数
     * @return int
     */
    public function getCountToday(): int
    {
        $date = date('Ymd', time());

        $count = false;

        // 获取当前抽奖总次数
        if ($this->cache_on >= 1)
        {
            $count = Cache::get('lucky_planet_count_' . $date);
        }
        // 没有存储
        if ($count === false)
        {
            try
            {
                $count = $this->whereTime('create_time', 'today')->count('id');

                if ($this->cache_on >= 1) Cache::set('lucky_planet_count_' . $date, $count, 86400);
            }
            catch (\Exception $e)
            {
                $count = 0;
            }
        }
        return $count;
    }

    /**
     * 获取用户今日抽奖情况
     * @param array $map
     * @return array|bool|mixed|\PDOStatement|string|\think\Model
     */
    public function getUserToday($map = [])
    {
        $uid = $map['uid'];

        $date = date('Ymd', time());

        $data = false;

        if ($this->cache_on >= 1)
        {
            // 获取用户今日抽奖情况
            $data = Cache::get(self::LUCKY_PLANET_USER_DATE . $uid . '_' . $date);
        }
        // 没有存储
        if ($data === false)
        {
            try
            {
                $data = $this->whereTime('create_time', 'today')->where('uid', $uid)->order('id DESC')->selectOrFail();

                $data = json_decode(json_encode($data, true), true);
            }
            catch (\Exception $e)
            {
                $data = [];
            }
            if ($this->cache_on >= 1)
            {
                Cache::set(self::LUCKY_PLANET_USER_DATE . $uid . '_' . $date, $data, 86400);
            }
        }
        return $data;
    }

    /**
     * 获取今日中奖用户
     * @param array $map
     * @return array|bool|false|mixed|\PDOStatement|string|\think\Collection
     */
    public function getWinToday($map = [])
    {
        $date = date('Ymd', time());

        $data = false;

        if ($this->cache_on >= 1)
        {
            // $data = Cache::get(self::WIN_TODAY . $date);
        }

        if ($data === false)
        {
            try
            {
                $data = $this->alias('uln')
                    ->field('uln.id pid,uln.uid,uln.prize,u.nickname,u.avatar,uln.status')
                    ->join('wechat_backup_07_18_14_43_00.app_user u', 'uln.uid=u.id', 'LEFT')
                    ->whereTime('create_time', 'today')->where('uln.status', '>', 0)->selectOrFail();

                $data = json_decode(json_encode($data, true), true);

            }
            catch (\Exception $e)
            {
                $data = [];
            }
            // 缓存开启，今日中奖信息写入缓存
            if ($this->cache_on >= 1)
            {
                Cache::set(self::WIN_TODAY . $date, $data, 86400);
            }
        }
        if (!empty($data))
        {
            foreach ($data as $k => $d)
            {
                $data[$k]['isself'] = 0;

                if (isset($map['uid']) && $map['uid'])
                {
                    if ($d['uid'] == $map['uid'])
                    {
                        $data[$k]['nickname'] = '你';

                        $data[$k]['isself'] = 1;
                    }
                }
                if (!$d['nickname']) $data[$k]['nickname'] = '匿名用户';
            }
        }
        return $data;
    }

    /**
     * 获取我的幸运星历史记录
     * @param array $map
     * @return array|mixed|\PDOStatement|string|\think\Model
     */
    public function getMyLuckyPlanets($map = [])
    {
        $uid = $map['uid'];

        try
        {
            $data = $this->alias('uln')
                ->field('uln.id,uln.prize,uln.planet_num,uln.create_time,uln.status,uln.tipsid,lt.text,question,answer')
                ->join('wechat_backup_07_18_14_43_00.app_question_answer qa', 'uln.id=qa.lid', 'LEFT')
                ->join('wechat_backup_07_18_14_43_00.app_lucky_tips lt', 'uln.tipsid=lt.id', 'INNER')
                ->where("uln.uid=$uid")
                ->order('uln.id DESC')
                ->selectOrFail();

            $data = json_decode(json_encode($data, true), true);
        }
        catch (\Exception $e)
        {
            $data = [];
        }
        if (!empty($data))
        {
            foreach ($data as $k => $d)
            {
                // 中奖未提问
                if (substr($d['planet_num'], 0, 2) == '00' && $d['status'] == 1)
                {
                    if (time() - (int)($d['create_time']) > 86400) $data[$k]['status'] = 4;// 判断是否已过期
                }

                if (substr($d['planet_num'], 0, 2) != '00') $data[$k]['tip'] = "你领到一颗{$d['prize']}，" . $d['text'];

                else $data[$k]['tip'] = $d['text'];
            }
        }

        return $data;
    }

    /**
     * 获取我的幸运星历史记录,分页
     * @param array $map
     * @return array|mixed|\think\Paginator
     */
    public function getMyLuckyPlanetsPaginate($map = [])
    {
        $uid = $map['uid'];

        try
        {
            $data = $this->alias('uln')
                ->field('uln.id,uln.prize,uln.planet_num,uln.create_time,uln.status,lt.text,question,answer')
                ->join('wechat_backup_07_18_14_43_00.app_question_answer qa', 'uln.id=qa.lid', 'LEFT')
                ->join('wechat_backup_07_18_14_43_00.app_lucky_tips lt', 'uln.tipsid=lt.id', 'INNER')
                ->where("uln.uid=$uid")
                ->order('uln.create_time DESC')
                ->paginate(10, false, ['page' => $map['page']]);

            $data = json_decode(json_encode($data, true), true);
        }
        catch (\Exception $e)
        {
            $data = [
                'total' => 0,
                'per_page' => 10,
                'current_page' => 1,
                'last_page' => 1,
                'data' => [],
            ];
        }

        if (!empty($data) && $data['total'] > 0)
        {
            foreach ($data['data'] as $k => $d)
            {
                // 中奖未提问
                if (substr($d['planet_num'], 0, 2) == '00' && $d['status'] == 1)
                {
                    if (time() - (int)($d['create_time']) > 86400) $data['data'][$k]['status'] = 4;// 判断是否已过期
                }

                if (substr($d['planet_num'], 0, 2) != '00') $data['data'][$k]['tip'] = "你领到一颗{$d['prize']}，" . $d['text'];

                else $data['data'][$k]['tip'] = $d['text'];
            }
        }
        return $data;
    }

    /**
     * 所有奖项
     * @return array|bool|mixed
     */
    public function getAllPrize()
    {
        $data = false;

        if ($this->cache_on >= 1)
        {
            $data = Cache::get(self::LUCKY_PLANET_PRIZE);
        }

        if ($data === false)
        {
            try
            {
                $temp = Db::table('wechat_backup_07_18_14_43_00.app_prize')->field('id,prize,v,planet_num')->where('status=0')->selectOrFail();

                $temp = json_decode(json_encode($temp, true), true);

                $data = [];

                if (!empty($temp)) foreach ($temp as $d) $data[$d['planet_num']] = ['prize' => $d['prize'], 'v' => $d['v']];

                if ($this->cache_on >= 1) Cache::set(self::LUCKY_PLANET_PRIZE, $data, 86400 * 3);

            }
            catch (\Exception $e)
            {
                $data = [];
            }
        }
        return $data;
    }

    /**
     * 获取所有奖项提示语
     */
    public function getAllPrizeTips()
    {
        $data = false;
        if ($this->cache_on >= 1)
        {
            $data = Cache::get(self::LUCKY_PLANET_PRIZE_TIPS);
        }
        if ($data === false)
        {
            try
            {
                $temp = Db::table('wechat_backup_07_18_14_43_00.app_lucky_tips')
                    ->field('id,planet_num,text')
                    ->where('status=0')
                    ->selectOrFail();

                $temp = json_decode(json_encode($temp, true), true);

                $data = [];

                if (!empty($temp))
                {
                    foreach ($temp as $d)
                    {
                        $data[$d['planet_num']][] = ['id' => $d['id'], 'text' => $d['text']];
                    }
                }

                if ($this->cache_on >= 1)
                {
                    Cache::set(self::LUCKY_PLANET_PRIZE_TIPS, $data, 86400 * 3);
                }
            }
            catch (\Exception $e)
            {
                $data = [];
            }
        }
        return $data;
    }

    /**
     * 添加并更新幸运星缓存
     * @param array $data
     * @return int|string
     * @throws ApiException
     */
    public function addLuckyPlanet($data = [])
    {
        try
        {
            $data['id'] = $this->allowField(true)->insertGetId($data);
        }
        catch (\Exception $e)
        {
            throw new ApiException('幸运星抽取失败');
        }

        $uid = $data['uid'];

        $date = date('Ymd', time());

        if ($this->cache_on >= 1)
        {
            // 获取用户今日抽奖情况
            $cache_data = Cache::get(self::LUCKY_PLANET_USER_DATE . $uid . '_' . $date);

            // 没有缓存
            if ($cache_data === false)
            {
                try
                {
                    $cache_data = $this->whereTime('create_time', 'today')->where('uid', $uid)->order('id DESC')->selectOrFail();

                    $cache_data = json_decode(json_encode($cache_data, true), true);

                    Cache::set(self::LUCKY_PLANET_USER_DATE . $uid . '_' . $date, $cache_data, 86400);
                }
                catch (\Exception $e)
                {
                    Cache::rm(self::LUCKY_PLANET_USER_DATE . $uid . '_' . $date);
                }
            } else
            {
                array_unshift($cache_data, $data);

                Cache::set(self::LUCKY_PLANET_USER_DATE . $uid . '_' . $date, $cache_data, 86400);
            }

            // 若用户中奖 需要更新幸运星首页缓存
            if ($data['status'] == 1) Cache::rm(self::WIN_TODAY . $date);
        }

        return $data['id'];
    }

    /**
     * 删除幸运星历史
     * @param int $uid
     * @param int $id
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function delLuckyPlanet(int $uid, int $id)
    {
        try
        {
            $data = $this->where('id', $id)->field('uid')->find();
            if (!$data || $data['uid'] != $uid)
            {
                return [
                    'status' => false,
                    'msg' => '幸运星不存在'
                ];
            }

            $data->delete(); // 软删除

            Cache::rm(self::REDIS_KEY_IDS . $uid);

            return [
                'status' => true,
                'msg' => '删除成功'
            ];
        }
        catch (\Exception $e)
        {
            Log::write('幸运星删除失败：' . $e->getMessage() . "；错误文件「{$e->getFile()}」错误行数「{$e->getLine()}」", 'error', true);
            return [
                'status' => false,
                'msg' => '服务异常，请稍后再试～'
            ];
        }
    }

    /**
     * 获取列表 page =-1：不分页；page>0：分页
     * @param array $map
     * @return array
     */
    public function getList($map = [])
    {
        $luckey_planet_ids = false;
        if ($this->cache_on >= 1)
        {
            $luckey_planet_ids = Cache::get(self::REDIS_KEY_IDS . $map['uid']);
        }
        if (!$luckey_planet_ids)
        {
            try
            {
                $luckey_planet_ids = $this
                    ->field('id,tipsid')
                    ->where('uid', $map['uid'])
                    ->order('id DESC')
                    ->select();
            }
            catch (\Exception $e)
            {
                // 错误信息写入日志
                \think\Log::write('获取幸运星列表错误:' . '[' . $map['uid'] . ']', 'error', true);
            }
            //获取数据
            $luckey_planet_ids = json_decode(json_encode($luckey_planet_ids, true), true);

            //存储所有ids
            if ($this->cache_on >= 1)
            {
                Cache::set(self::REDIS_KEY_IDS . $map['uid'], $luckey_planet_ids, $this->cache_time);
            }
        }

        if (count($luckey_planet_ids) == 0)
        {//如果ids为空，那么直接返回
            return $luckey_planet_ids;
        }

        if ($map['page'] == -1)
        {//获取所有
            $data_list['data'] = $this->processList($luckey_planet_ids, $map['uid']);
        } else
        {//分页获取
            //进行分页返回数据
            $total = count($luckey_planet_ids);//统计有多少个id
            $data_list = getPaginatorData($total, $map['page']);//获取数据分页信息
            $result = array_slice($luckey_planet_ids, $data_list['start'], $data_list['per_page']);//获取分页后的id数组
            unset($data_list['start']);
            unset($data_list['end']);
            $data_list['data'] = $this->processList($result, $map['uid']);
        }


        return $data_list;
    }


    /**
     * 获取详情
     * @param array $all_list
     * @return array
     */
    public function getDetails($all_list = [])
    {
        $result = [];
        $ids = $this->getAllNotCachedIds($all_list, self::REDIS_KEY_DETAIL);
        try
        {
            if (strlen($ids) > 0)
            {
                $where = 'id in(' . $ids . ')';
                $result = $this
                    ->field('id,prize,planet_num,create_time,status,is_exchange,tipsid,type')
                    ->where($where)
                    ->order('id DESC')
                    ->select();
                $result = json_decode(json_encode($result, true), true);
                if ($this->cache_on >= 1)
                    foreach ($result as $v)
                        Cache::set(self::REDIS_KEY_DETAIL . $v['id'], $v, $this->cache_time);
            }
            if ($this->cache_on >= 1)//如果缓存打开，循环获取，因为缓存里已经有了数据
            {
                $result = [];
                foreach ($all_list as $v)
                    $result[] = Cache::get(self::REDIS_KEY_DETAIL . $v['id']);
            }
        }
        catch (\Exception $e)
        {
            $result = [];
            // 错误信息写入日志
            \think\Log::write('获取幸运星详情错误' . PHP_EOL . $e->getMessage() . PHP_EOL . '[' . $ids . ']', 'error');
        }
        return $result;
    }

    /**
     * 处理返回数据 列表
     * @param $result
     * @param $uid
     * @return array
     */
    public function processList($result, $uid)
    {
        $data_list = [];

        // 循环获取领取详情列表
        $lucky_planet_details = $this->getDetails($result);

        // 循环获取幸运星词条详情列表
        $tips_ids = [];
        foreach ($result as $mid)
        {
            $tips_ids[]['id'] = $mid['tipsid'];
        }
        $tips = (new LuckyTips())->getDetails($tips_ids);

        $tipsText = [];

        if (!empty($tips))
        {
            foreach ($tips as $k => $tip)
            {
                $tipsText[$tip['id']] = $tip;
            }
        }

        // 获取该用户所有的回答
        $qa_ids = (new LuckyQuestionAnswer())->getList($uid);

        foreach ($result as $k => $mid)
        {
            $lucky_planet_detail = $lucky_planet_details[$k];
            $tip = isset($tipsText[$mid['tipsid']]) ? $tipsText[$mid['tipsid']] : '';

            foreach ($qa_ids as $qa_detail)
            {
                if ($qa_detail['lid'] == $mid['id'])
                {
                    $lucky_planet_detail['question'] = $qa_detail['question'];
                    $lucky_planet_detail['answer'] = $qa_detail['answer'];
                    $lucky_planet_detail['question_time'] = $qa_detail['question_time'];
                    $lucky_planet_detail['answer_time'] = $qa_detail['answer_time'];
                }
            }
            $lucky_planet_detail['text'] = $tip['text'];
            try
            {
                $substrPlanetNum = substr($lucky_planet_detail['planet_num'], 0, 2);
            }
            catch (\Exception $e)
            {
                \think\Log::write(var_export($lucky_planet_details, true), 'log', true);
                $substrPlanetNum = '';
            }
            // 中奖未提问
            if ($substrPlanetNum == '00' && $lucky_planet_detail['status'] == 1)
            {
                if (time() - (int)($lucky_planet_detail['create_time']) > 86400) $lucky_planet_detail['status'] = 4;// 判断是否已过期
            }
            if ($substrPlanetNum != '00')
            {
                $tip = "你领到一颗{$lucky_planet_detail['prize']}，" . $tip['text'];
            } else
            {
                $tip = $tip['text'];
                if (isset($lucky_planet_detail['type']) && $lucky_planet_detail['type'] == 2)
                {
                    $tip = str_replace('看盘', '提问', $tip);
                }
            }
            $lucky_planet_detail['tip'] = $tip;

            unset($lucky_planet_detail['type']);
            $data_list[] = $lucky_planet_detail;
        }
        return $data_list;
    }


    /**
     * 获取用户中奖记录
     * @param array $map
     * @return array
     */
    public function getUserPrize($map = [])
    {
        $where = ['uid' => $map['uid'], 'status' => ['>', 0]];

        try
        {
            $luckey_planet_ids = $this
                ->field('id,tipsid')
                ->where($where)
                ->order('id DESC')
                ->select();
        }
        catch (\Exception $e)
        {
            // 错误信息写入日志
            \think\Log::write('获取幸运星列表错误:' . '[' . $map['uid'] . ']', 'error', true);
        }
        //获取数据
        $luckey_planet_ids = json_decode(json_encode($luckey_planet_ids, true), true);


        if (count($luckey_planet_ids) == 0)
        {//如果ids为空，那么直接返回
            return $luckey_planet_ids;
        }

        //获取所有
        $data_list = $this->processList($luckey_planet_ids, $map['uid']);

        return $data_list;
    }


    /**
     * 获取用户分组后的幸运星数据
     * @param int $uid
     */
    public function getGroupCardPlanet($uid = 0)
    {

        try
        {
            $data = $this->alias('ln')
                ->field('lt.text,ln.id,ln.status,ln.prize,ln.create_time,ln.planet_num,count(ln.planet_num) as count')
                ->join('wechat_backup_07_18_14_43_00.app_lucky_tips lt', 'ln.tipsid=lt.id', 'INNER')
                ->where('ln.uid', $uid)
                ->group('ln.planet_num')
                ->order('ln.planet_num', 'ASC')
                ->select();
            $data = json_decode(json_encode($data, true), true);

        }
        catch (\Exception $e)
        {
            $this->error = '获取幸运星失败';
            return false;
        }

        return $data;
    }
}
